//Copyright (C) 2008 QMTech (http://www.qmtech.net)

//This program is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.

//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.

//You should have received a copy of the GNU General Public License
//along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;

using MonoDevelop.Ide.Gui;
using MonoDevelop.Ide.Gui.Content;
using MonoDevelop.Projects.Dom;
using MonoDevelop.Projects.Dom.Parser;
using MonoDevelop.Projects.Gui;
using MonoDevelop.Projects.Gui.Completion;
using Castle.MonoRail.Framework.Helpers;

namespace MonoDevelop.Castle.Monorail
{
	
	
	public class NVelocityCompletion : CompletionTextEditorExtension
	{
		
		public NVelocityCompletion(){		}

		public override void Initialize (){
			base.Initialize ();
		}

		public override bool ExtendsEditor (Document doc, IEditableTextBuffer editor){
			if (doc == null || String.IsNullOrEmpty (doc.Name))
				return false;
			return Path.GetExtension (doc.Name) == ".vm";
		}

		public override ICompletionDataList HandleCodeCompletion (ICodeCompletionContext completionContext, char completionChar){
			switch (completionChar) {
			case '#':
				return GenerateKeywordsCompletion();
			case '$':
				return GenerateHelpersCompletion();
			case '.':
				return GenerateHelperContentCompletion (completionContext);
			default:
				return null;
			}
		}

		ICompletionDataList GenerateHelperContentCompletion (ICodeCompletionContext completionContext){
			CompletionDataList list = null;
			string trimmedLine = Editor.GetLineText (completionContext.TriggerLine).Trim ();
			Match match = Regex.Match(trimmedLine, @".*?\$\w*?Helper\.");
			if (match.Success){
				int start = trimmedLine.LastIndexOf("$");
				int end = trimmedLine.LastIndexOf(".");
				string helperName = trimmedLine.Substring(start+1, end-start-1);
				list = new CompletionDataList ();
				string fullName = "Castle.MonoRail.Framework.Helpers." + helperName + ",Castle.MonoRail.Framework";
				Type helperType = Type.GetType(fullName);
				foreach(MethodInfo minfo in helperType.GetMethods()){
					if (minfo.DeclaringType == helperType){
						list.Add (minfo.Name, s_ImgFunc, null, minfo.Name);
					}
				}
			}
			return list;
		}
		
		public override IParameterDataProvider HandleParameterCompletion (ICodeCompletionContext completionContext, char completionChar){
			string trimmedLine = Editor.GetLineText (completionContext.TriggerLine).Trim ();
			Match match = Regex.Match(trimmedLine, @".*?\$\w*?Helper\.\w*?\(");
			if (completionChar == '(' && match.Success){
				int startHelper = trimmedLine.LastIndexOf("$");
				int endHelper = trimmedLine.LastIndexOf(".");
				string helperName = trimmedLine.Substring(startHelper+1, endHelper-startHelper-1);
				string fullName = "Castle.MonoRail.Framework.Helpers." + helperName + ",Castle.MonoRail.Framework";
				Type helperType = Type.GetType(fullName);
				int start = trimmedLine.LastIndexOf(".");
				int end = trimmedLine.LastIndexOf("(");
				string methodName = trimmedLine.Substring(start+1, end-start-1);
				return new NVelocityMethodParameterDataProvider(helperType, methodName);
			}
			else{
				return null;
			}
			
		}

		static ICompletionDataList GenerateKeywordsCompletion (){
			CompletionDataList list = new CompletionDataList ();
			list.Add ("set", s_ImgFunc, null, "set");
			list.Add ("if", s_ImgFunc, null, "if");
			list.Add ("else", s_ImgFunc, null, "else");
			list.Add ("foreach", s_ImgFunc, null, "foreach");
			list.Add ("include", s_ImgFunc, null, "include");
			list.Add ("parse", s_ImgFunc, null, "parse");
			list.Add ("stop", s_ImgFunc, null, "stop");
			list.Add ("evaluate", s_ImgFunc, null, "evaluate");
			list.Add ("define", s_ImgFunc, null, "define");
			list.Add ("macro", s_ImgFunc, null, "macro");
			list.Add ("end", s_ImgFunc, null, "end");
			return list;
		}

		static ICompletionDataList GenerateHelpersCompletion (){
			CompletionDataList list = new CompletionDataList ();
			list.Add ("FormHelper", s_ImgFunc, null, "FormHelper");
			list.Add ("UrlHelper", s_ImgFunc, null, "UrlHelper");
			list.Add ("AjaxHelper", s_ImgFunc, null, "AjaxHelper");
			list.Add ("PaginationHelper", s_ImgFunc, null, "PaginationHelper");
			list.Add ("WizardHelper", s_ImgFunc, null, "WizardHelper");
			list.Add ("TextHelper", s_ImgFunc, null, "TextHelper");
			list.Add ("Effects2Helper", s_ImgFunc, null, "Effects2Helper");
			list.Add ("DateFormatHelper", s_ImgFunc, null, "DateFormatHelper");
			return list;
		}
		
		const string s_ImgFunc  = "md-method";
		

	}
}
